import React, {memo, useEffect, useState} from "react";
import {useSelector} from "react-redux";
import {MENU_STYLE} from "../config";
import arrDown from "../images/arrangeDown.png";
import arrRight from "../images/arrangeRight.png";
import arrRightChecked from "../images/arrangeRightChecked.png";
import arrDownChecked from "../images/arrangeDownChecked.png";
import {Dropdown, Menu, message} from "antd";
import {deepClone, exportExcel, generateUUID, getRandomColor} from "../../../../common/utils";
import * as XLSX from "xlsx";
import {WELL_TYPE} from "../../store/constants";

export default memo(function PlateSampleLibrary(props) {
  const {wells, setWells, setShowSampleLibrary, sample, setSample, samples, setSamples, target, setTarget, group, setGroup} = props;
  const newFileName = samples.namePrefix + "_" + samples.startingValue + "" + samples.interval + "" + samples.digits + "_" + samples.task + ".xlsx";
  const {isCN, data} = useSelector(state => ({
    isCN: state.languageReducer.isCN,
    data: state.dataReducer.data
  }));
  const sampleRange = ['Selected Wells', 'All Wells'];
  const wellsType = ["Std", "Unk", "Ntc", "Neg", "Pos", "Nrt"];
  const [list, actionlist] = useState([]);
  const [header, setHeader] = useState([
    {
      title: 'namePrefix',
      dataIndex: 'namePre',
      key: 'namePre',
      className: 'text-monospace'
    }, {
      title: 'startValue',
      dataIndex: 'startVal',
      key: 'startVal'
    }, {
      title: 'interval',
      dataIndex: 'inter',
      key: 'inter'
    }, {
      title: 'digits',
      dataIndex: 'digit',
      key: 'digit'
    }, {
      title: 'task',
      dataIndex: 'tas',
      key: 'tas'
    }, {
      title: 'isDown',
      dataIndex: 'isdown',
      key: 'isdown'
    }, {
      title: 'fileName',
      dataIndex: 'file',
      key: 'file'
    }
  ]);
  const [excelList, setExcelList] = useState([]);

  let cloneSample = [];
  let cloneWells = [];
  let cloneTarget = [];
  let cloneGroup = [];


  useEffect(() => {
    if (list.length > 0) {
      // list写入数据库
    }
  }, [list]);

  useEffect(() => {
    const excelList = [{
      namePre: samples.namePrefix,
      startVal: samples.startingValue,
      inter: samples.interval,
      digit: samples.digits,
      tas: samples.task,
      isdown: samples.isDown,
      file: newFileName
    }];
    setExcelList(excelList);
  }, [samples]);

  //更改Range选取wells范围，只有all
  function changeRange(value) {
    cloneSample = deepClone(samples, cloneSample);
    cloneSample.sampleRange = value;
    setSamples(cloneSample);
    if (cloneSample.sampleRange === 'All Wells') {
      cloneWells = deepClone(wells, cloneWells);
      if (wells.some(item => !item.selected)) {
        cloneWells.forEach(well => well.selected = true);
      } else {
        cloneWells.forEach(well => well.selected = false);
      }
      setWells(cloneWells);
      selectTargetAuto(cloneWells);
      selectSampleOrGroupAuto(cloneWells, deepClone(sample, cloneSample), setSample, "sampleName");
      selectSampleOrGroupAuto(cloneWells, deepClone(group, cloneGroup), setGroup, "groupName");
    }
  }

  //  选择well后在target处自动变更Opt
  function selectTargetAuto(_wells) {
    cloneTarget = deepClone(target, cloneTarget);
    cloneTarget.forEach(item => item.opt = false);
    let selectedWells = _wells.filter(well => well.selected),
      wellSelectedCount = selectedWells.length,
      targetsName = new Map();
    _wells.forEach(well => well.selected && well.targets.forEach(target =>
      targetsName.has(target.name)
        ? targetsName.set(target.name, targetsName.get(target.name) + 1)
        : targetsName.set(target.name, 1)));
    targetsName.forEach((targetNameCount, targetName) => targetNameCount <= wellSelectedCount && cloneTarget.forEach(item => item.name === targetName && (item.opt = true)));
    setTarget(cloneTarget);
  }

  //  选择well后在sample或group处自动变更Opt
  function selectSampleOrGroupAuto(_wells, cloneItem, setAction, type) {
    cloneItem.forEach(item => item.opt = false);
    let selectedWells = _wells.filter(well => well.selected),
      wellSelectedCount = selectedWells.length,
      nameMap = new Map();
    _wells.forEach(well => {
      if (well.selected && well[type] !== "") {
        nameMap.has(well[type])
          ? nameMap.set(well[type], nameMap.get(well[type]) + 1)
          : nameMap.set(well[type], 1);
      }
    });
    nameMap.forEach((groupNameCount, groupName) => groupNameCount <= wellSelectedCount && cloneItem.forEach(item => item.name === groupName && (item.opt = true)));
    setAction(cloneItem);
  }

  //改变start value
  function changeNumberOfSample(value) {
    cloneSample = deepClone(samples, cloneSample);
    cloneSample.startingValue = value;
    setSamples(cloneSample);
  }

  //改变Interval
  function changeIntervalSample(value) {
    cloneSample = deepClone(samples, cloneSample);
    cloneSample.interval = value;
    setSamples(cloneSample);
  }

  //改变Digits
  function changeDigitsSample(value) {
    cloneSample = deepClone(samples, cloneSample);
    cloneSample.digits = value;
    setSamples(cloneSample);
  }

  //改变Task
  function changeTaskSample(value) {
    cloneSample = deepClone(samples, cloneSample);
    cloneSample.task = value;
    setSamples(cloneSample);
  }

  //改变sample的Name
  function changeSampleName(value) {
    cloneSample = deepClone(samples, cloneSample);
    cloneSample.namePrefix = value;
    setSamples(cloneSample);
  }

  //选择arrange
  function selectArrange(value) {
    cloneSample = deepClone(samples, cloneSample);
    cloneSample.isDown = value;
    setSamples(cloneSample);
  }

  //sample自动布孔减少代码冗余
  function setSampleWells(index, namePrefix, startingValue, interval, digits, task) {
    let uuid = generateUUID(),
      color = getRandomColor(),
      nameAfter = ('' + startingValue).padStart(digits, '0');
    cloneWells[index].sampleName = namePrefix + nameAfter;
    cloneWells[index].sampleColor = color;
    cloneWells[index].type = task;
    cloneWells[index].sampleUuid = uuid;
    let autoDownName = cloneWells[index].sampleName;
    cloneSample.unshift({
      uuid: uuid,
      opt: true,
      color: color,
      comments: "",
      type: task,
      name: autoDownName,
      control: false,
      id: "",
      mark: ""
    });
  }

  //Apply执行重新命名自动布局
  function autoSampleName(namePrefix, startingValue, interval, digits, isDown, task) {
    namePrefix = samples.namePrefix;
    startingValue = samples.startingValue;
    interval = samples.interval;
    digits = samples.digits;
    isDown = samples.isDown;
    task = samples.task;
    cloneWells = deepClone(wells, cloneWells);
    cloneSample = deepClone(sample, cloneSample);
    if (!cloneWells.some(item => item.selected)) {  //  没有选择wells
      return message.warn("Please select wells.");
    }
    /*let rowNumber = cloneWells.find(item => item.selected).row;  //  第一次出现被选中well的行数
     let colNumber = cloneWells.find(item => item.selected).col;  //  第一次出现被选中well的列数*/
    if (isDown) {
      for (let i = 0; i < 12; i++) {
        for (let j = 0; j < 8; j++) {
          let index = j * 12 + i;
          if (cloneWells[index].selected) {
            setSampleWells(index, namePrefix, startingValue, interval, digits, task);
            startingValue += interval;
            if (index === 95) {
              break;
            }
          }
        }
      }
    } else {
      // 水平递增
      for (let i = 0; i < 96; i++) {
        if (cloneWells[i].selected) {
          setSampleWells(i, namePrefix, startingValue, interval, digits, task);
          startingValue += interval;
        }
      }
    }
    setSample(cloneSample);
    setWells(cloneWells);
  }

  /**
   * 导入excel的函数
   * @param {*} file
   */
  function importsExcel(file) {
    //使用promise导入
    return new Promise((resolve, reject) => {
      // 获取上传的文件对象
      const {files} = file.target; //获取里面的所有文件
      //获得文件的名称
      let name = files[0].name;
      //获得文件后缀
      let fileAfter = name.substr(name.lastIndexOf(".") + 1).toString();
      // 通过FileReader对象读取文件
      const fileReader = new FileReader();
      fileReader.onload = event => { //异步操作  excel文件加载完成以后触发
        try {
          // 判断文件类型是否正确
          if (fileAfter !== "xls" && fileAfter !== "xlsx") {//&& 都为真才为真，||有一个为真则为真
            message.error("选择Excel格式的文件导入！");
            return false;
          }
          const {result} = event.target;
          // 以二进制流方式读取得到整份excel表格对象
          const workbook = XLSX.read(result, {type: 'binary'});
          let data = []; // 存储获取到的数据
          // 遍历每张工作表进行读取（这里默认只读取第一张表）
          for (const sheet in workbook.Sheets) {
            if (workbook.Sheets.hasOwnProperty(sheet)) {
              data = data.concat(XLSX.utils.sheet_to_json(workbook.Sheets[sheet]));
            }
          }
          data = data.concat(name);
          // console.log(data);
          resolve(data);//导出数据
        } catch (e) {
          // 这里可以抛出文件类型错误不正确的相关提示
          reject("文件类型错误");//导出失败
        }
      };
      // 以二进制方式打开文件
      fileReader.readAsBinaryString(files[0]);
    });
  }

  return (
    <div className="plateSampleLibrary">
      <header>
        <div>
          <p>{isCN ? "样本编辑" : "Sample Editors"}</p>
          <p onClick={() => setShowSampleLibrary(false)}/>
          <label htmlFor="saveExcel"/>
        </div>
        <hr/>
      </header>
      <hr/>
      <div className="sampleEditorLeft">
        <header style={{'marginLeft': isCN ? '-13%' : "-22%"}}>{isCN ? "自动编辑" : "Automatic editor"}</header>
        <div>
          <div>{isCN ? "选择样本" : "Sample Range"}</div>
          <Dropdown
            overlay={
              <Menu>
                {
                  sampleRange.map(item => (
                    <Menu.Item key={item}>
                      <div style={MENU_STYLE} onClick={() => changeRange(item)}>{item}</div>
                    </Menu.Item>
                  ))
                }
              </Menu>
            }
            placement="topCenter"
            trigger={['click']}
          >
            <div>{samples.sampleRange}</div>
          </Dropdown>
        </div>
        <div>
          <div>{isCN ? "名称前缀" : "Name Prefix"}</div>
          <input type="text" maxLength="8" value={samples.namePrefix || ""}
                 onChange={e => changeSampleName(e.target.value)}/>
        </div>
        <div>
          <div>{isCN ? "起始值" : "Starting Value"}</div>
          <input type="number" value={samples.startingValue || ""}
                 onChange={e => changeNumberOfSample(Number(e.target.value))}/>
        </div>
        <div>
          <div>{isCN ? "间隔" : "Interval"}</div>
          <input type="text" value={samples.interval || ""}
                 onChange={e => changeIntervalSample(Number(e.target.value))}/>
        </div>
        <div>
          <div>{isCN ? "后缀位数" : "Digits"}</div>
          <input type="text" value={samples.digits || ""}
                 onChange={e => changeDigitsSample(Number(e.target.value))}/>
        </div>
        <div>
          <div>{isCN ? "类型" : "Task"}</div>
          <Dropdown
            overlay={
              <Menu>
                {
                  wellsType.map(item => (
                    <Menu.Item key={item}>
                      <div style={MENU_STYLE} onClick={() => changeTaskSample(item)}>{item}</div>
                    </Menu.Item>
                  ))
                }
              </Menu>
            }
            placement="topCenter"
            trigger={['click']}
          >
            <div>{samples.task}</div>
          </Dropdown>

        </div>
        <div className="arrangeCheck">
          <div>{isCN ? "顺序" : "Arrange"}</div>
          <div onClick={() => {
            selectArrange(true);
          }}
               style={{backgroundImage: (samples.isDown + '').toLowerCase() === "true" ? `url(${arrDownChecked})` : `url(${arrDown})`}}
          />
          <div onClick={() => selectArrange(false)}
               style={{backgroundImage: (samples.isDown + '').toLowerCase() === "false" ? `url(${arrRightChecked})` : `url(${arrRight})`}}
          />
        </div>
      </div>
      <div className="sampleEditorRight">
        <div>
          <div style={{top: "-32"}}>{isCN ? "从表格导入" : "Load from Excel"}</div>
        </div>
        <div>
          <div style={{top: "-24"}}>{isCN ? "选择文件" : "Select the Name File"}</div>
          <section className="tableStyle_ scrollBarStyle" style={{overflow: "auto"}}>
            <ul style={{display: "none"}} id="pcrTable">
              <li>{"fileName:  " + samples.fileName}</li>
              <li>{"namePrefix:  " + samples.namePrefix}</li>
              <li>{"startingValue:  " + samples.startingValue}</li>
              <li>{"interval:  " + samples.interval}</li>
              <li>{"digits:  " + samples.digits}</li>
              <li>{"task:  " + samples.task}</li>
              <li>{"isDown:  " + samples.isDown}</li>
            </ul>
          </section>
          <section className="excelStyle">
            <input type="file" id="file" accept=".xlsx,.xls" style={{display: "none"}}
                   onClick={(e) => {
                     e.target.value = null;
                   }}
                   onChange={(e) => {
                     importsExcel(e).then(function (excelData, i) {
                       try {
                         cloneWells = deepClone(wells, cloneWells);
                         cloneSample = deepClone(sample, cloneSample);
                         // console.log(excelData);
                         if (cloneWells.some(item => item.selected)) {  //  没有选择wells
                           return message.warn("Please clear selected wells.");
                         }
                         if (cloneWells.some(item => item.sampleColor !== "")) {
                           // console.log(cloneSample);
                           cloneSample.forEach(item => item.opt = false);
                           cloneWells.forEach(well => {
                             well.groupColor = "";
                             well.groupName = "";
                             well.sampleName = "";
                             well.sampleUuid = "";
                             well.groupUuid = "";
                             well.groupColor = "";
                             well.targets = [];
                             well.type = "";
                           });
                         }
                         var cols = excelData[0].WellPosition.split("")[0];
                         var cols_ = excelData[1].WellPosition.split("")[0];
                         // console.log(data);
                         if (cols === cols_) { //横向布局
                           for (let i = excelData[0].Well - 1; i < excelData[excelData.length - 2].Well; i++) {
                             if (excelData[0].Well > 95) {
                               return message.warn("Fail error!Please Reload excel.");
                             }
                             let uuid = generateUUID(),
                               color = getRandomColor();
                             let dataIndex = excelData.findIndex(item => item.Well === i + 1);
                             cloneWells[i].sampleName = excelData[dataIndex].SampleName;
                             cloneWells[i].sampleColor = getRandomColor();
                             cloneWells[i].type = WELL_TYPE.UNK;
                             cloneWells[i].sampleUuid = uuid;
                             let autoLevelName = cloneWells[i].sampleName;
                             cloneSample.unshift({
                               uuid: uuid,
                               opt: true,
                               color: color,
                               comments: "",
                               type: WELL_TYPE.UNK,
                               name: autoLevelName,
                               control: false,
                               id: "",
                               mark: ""
                             });
                             let addLevl = excelData[dataIndex + 1].Well - excelData[dataIndex].Well;
                             if (addLevl > 1) {
                               i = i + addLevl;
                             }
                           }
                         } else { //纵向向布局 垂直递增
                           let arr = [];
                           for (let j = 0; j < excelData.length - 1; j++) {
                             let map = new Map([['A', 1], ['B', 2], ['C', 3], ['D', 4], ['E', 5], ['F', 6], ['G', 7], ['H', 8]]);
                             arr[j] = {
                               sampleName_: excelData[j].SampleName,
                               WellPosition_: excelData[j].WellPosition,
                               col_: map.get(excelData[j].WellPosition.split('')[0]) - 1,  //行
                               row_: excelData[j].WellPosition.split('')[2] === undefined ? excelData[j].WellPosition.split('')[1] - 1 :
                                 excelData[j].WellPosition.split('')[1] + excelData[j].WellPosition.split('')[2] - 1//列
                             };
                             let uuid = generateUUID(),
                               color = getRandomColor();
                             let dataIndex = cloneWells.findIndex(item => {
                               return item.col === arr[j].row_ && item.row === arr[j].col_;
                             });
                             cloneWells[dataIndex].col = arr[j].row_;
                             cloneWells[dataIndex].row = arr[j].col_;
                             cloneWells[dataIndex].sampleName = arr[j].sampleName_;
                             cloneWells[dataIndex].sampleColor = getRandomColor();
                             cloneWells[dataIndex].type = WELL_TYPE.UNK;
                             cloneWells[dataIndex].sampleUuid = uuid;
                             let autoLevelName = cloneWells[dataIndex].sampleName;
                             cloneSample.unshift({
                               uuid: uuid,
                               opt: true,
                               color: color,
                               comments: "",
                               type: WELL_TYPE.UNK,
                               name: autoLevelName,
                               control: false,
                               id: "",
                               mark: ""
                             });
                           }
                           // console.log(arr);
                         }
                         setWells(cloneWells);
                         setSample(cloneSample);
                       } catch (e) {
                         // return message.warn("文件内容格式错误.");
                         console.log(e);
                       }
                       document.getElementById("pcrTable").style.display = "block";
                     });
                   }
                   }/>
            <label htmlFor="file">{isCN ? "浏览" : "Browse"}</label>
            <div onClick={autoSampleName}>{isCN ? "应用" : "Apply"}</div>
            <button id="saveExcel" style={{opacity: "0"}} onClick={() => {
              exportExcel(header, excelList, newFileName);
            }
            }>
            </button>
          </section>
        </div>
      </div>
    </div>
  );
});


















